//
//  Eyepiece+Watermark.swift
//  WatermarkCamera
//
//  Created by AxcLogo on 4/7/2024.
//

import UIKit
import Foundation
import AxcBedrock

extension Eyepiece {
    // MARK: - 水印方法

    // MARK: 增

    /// 添加水印图片
    /// - Parameters:
    ///   - image: 水印图片
    ///   - blendMode: 混合模式
    func appendWatermark(image: UIImage) {
        beginWatermarkResponseChain() // 准备开始

        let wmOutput: Watermark = .init(image: image)

        watermarkList.append(wmOutput)

        commitWatermarkResponseChain() // 提交更新
    }

    func appendElementWatermark(view: UIView) {
        beginWatermarkResponseChain() // 准备开始

        let wmOutput: Watermark = .init(view: view)

        watermarkList.append(wmOutput)

        commitWatermarkResponseChain() // 提交更新
    }

    /// 插入水印图片
    /// - Parameters:
    ///   - image: 水印图片
    ///   - blendMode: 混合模式
    ///   - index: 索引
    func insterWatermark(image: UIImage, at index: Int) {
        beginWatermarkResponseChain() // 准备开始

        let wmOutput: Watermark = .init(image: image)

        watermarkList.insert(wmOutput, at: index)

        commitWatermarkResponseChain() // 提交更新
    }

    // MARK: 删

    /// 移除水印
    /// - Parameter index: 索引
    func removeWatermark(at index: Int) {
        beginWatermarkResponseChain() // 准备开始

        watermarkList.remove(at: index)

        commitWatermarkResponseChain() // 提交更新
    }

    /// 移除所有水印
    func removeAllWatermark() {
        beginWatermarkResponseChain() // 准备开始

        watermarkList.removeAll()

        commitWatermarkResponseChain() // 提交更新
    }

    // MARK: 改

    /// 移动水印顺序
    /// - Parameters:
    ///   - index: 从第几个索引
    ///   - toIndex: 到第几个索引
    func moveWatermark(form index: Int, to toIndex: Int) {
        beginWatermarkResponseChain() // 准备开始

        let formWatermark = watermarkList[index]

        watermarkList.remove(at: index)

        watermarkList.insert(formWatermark, at: toIndex)

        commitWatermarkResponseChain() // 提交更新
    }

    /// 更新水印图片
    /// - Parameters:
    ///   - image: 图片
    ///   - index: 索引
    func replaceWatermark(image: UIImage, at index: Int) {
        guard let watermark = watermarkList.axc.object(at: index),

              let picture = watermark.output as? GPUImagePicture else { return }

        picture.replaceTextureImage(image)

        picture.processImage()
    }

    /// 交换两个水印的顺序
    /// - Parameters:
    ///   - index: 从第几个索引
    ///   - toIndex: 到第几个索引
    func exchangeWatermark(form index: Int, to toIndex: Int) {
        beginWatermarkResponseChain() // 准备开始

        let formWatermark = watermarkList[index]

        let toWatermark = watermarkList[toIndex]

        watermarkList[index] = formWatermark

        watermarkList[toIndex] = toWatermark

        commitWatermarkResponseChain() // 提交更新
    }

    /// 反转所有水印顺序
    func reversedAllWatermark() {
        beginWatermarkResponseChain() // 准备开始

        watermarkList = watermarkList.reversed()

        commitWatermarkResponseChain() // 提交更新
    }
}

extension Eyepiece {
    /// 准备开始刷新水印响应链
    func beginWatermarkResponseChain() {
        // 准备重新构造水印链、移除所有水印链

        for watermark in watermarkList {
            watermark.output?.removeAllTargets()

            watermark.blendFilter.removeAllTargets()
        }
    }

    /// 提交刷新水印响应链
    func commitWatermarkResponseChain() {
        if watermarkList.isEmpty {
            setWatermarkHeader(watermarkChain.footer)

        } else {
            var lastBlend: GPUImageFilter?

            for watermark in watermarkList {
                let blend = watermark.blendFilter

                if let lastBlend = lastBlend {
                    lastBlend.addTarget(blend) // 多重水印混合

                } else {
                    setWatermarkHeader(blend) // 第一个水印混合
                }

                watermark.output?.addTarget(blend)

                lastBlend = blend
            }

            guard let lastBlend = lastBlend else { return }

            setWatermarkFooter(lastBlend)
        }
    }

    /// 设置水印链头
    func setWatermarkHeader(_ blend: GPUImageFilter) {
        watermarkChain.header.removeAllTargets()

        watermarkChain.header.addTarget(blend)
    }

    /// 设置水印链尾
    func setWatermarkFooter(_ blend: GPUImageFilter) {
        blend.addTarget(watermarkChain.footer)
    }

    func updateElement() {
        for watermark in watermarkList {
            if let element = watermark.output as? GPUImageUIElement {
                element.update()
            }
        }
    }
}
